package com.yilin.tms.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.tms.core.application.ReturnData;
import com.yilin.tms.core.entity.system.system.FunctionApi;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.grant.GrantFunctionApi;
import com.yilin.tms.core.entity.user.organize.MemberType;
import com.yilin.tms.core.entity.user.organize.Organize;
import com.yilin.tms.core.remote.ISystemRemote;
import com.yilin.tms.user.service.IGrantFunctionApiService;
import com.yilin.tms.user.service.IMemberTypeService;
import com.yilin.tms.user.service.IOrganizeService;
import com.yilin.tms.user.mapper.GrantFunctionApiMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class GrantFunctionApiService extends ServiceImpl<GrantFunctionApiMapper, GrantFunctionApi> implements IGrantFunctionApiService {

    @Resource
    private GrantFunctionApiMapper grantFunctionApiMapper;

    @Resource
    private ISystemRemote systemRemote;

    @Resource
    private IMemberTypeService memberTypeService;
    @Resource
    private IOrganizeService organizeService;

    /**
     * 获取平台所有权限
     */
    @Override
    public List<FunctionApi> getAllFunctionApiList() {
        ReturnData<List<FunctionApi>> returnData = systemRemote.getAllFunctionApiList();
        if (returnData == null) return new ArrayList<>();
        return returnData.getData();
    }

    /**
     * 获取当前组织会员下拥有的权限列表
     */
    @Override
    public List<FunctionApi> getMineGrantFunctionApiList(String organizeId) {
        Organize organize = organizeService.getOrganizeById(organizeId);
        List<FunctionApi> functionApiList = null;
        if (organize.getUserType() != UserType.adminUser) {
            MemberType mineMemberType = memberTypeService.getDefaultMemberTypeByOrganizeId(organize.getSuperiorPlatOrganizeId(), organize.getUserType());
            if (mineMemberType != null) functionApiList = getGrantFunctionApiList(mineMemberType.getId());
        } else {
            functionApiList = getAllFunctionApiList();
        }
        return functionApiList;
    }

    /**
     * 获取当前组织会员下拥有的权限ID列表
     */
    @Override
    public List<String> getMineGrantFunctionApiCodeList(String organizeId) {
        Organize organize = organizeService.getOrganizeById(organizeId);
        List<String> functionApiCodeList = null;
        if (organize.getUserType() != UserType.adminUser) {
            MemberType mineMemberType = memberTypeService.getDefaultMemberTypeByOrganizeId(organize.getSuperiorPlatOrganizeId(), organize.getUserType());
            if (mineMemberType != null) functionApiCodeList = getGrantFunctionApiCodeList(mineMemberType.getId());
        } else {
            functionApiCodeList = ArrayUtil.fieldAdd(getAllFunctionApiList(), FunctionApi::getCode);
        }
        return functionApiCodeList;
    }

    /**
     * 获取会员授权列表
     */
    @Override
    public List<FunctionApi> getGrantFunctionApiList(String memberTypeId) {
        List<String> grantApiCodeList = getGrantFunctionApiCodeList(memberTypeId);
        if (grantApiCodeList.isEmpty()) return new ArrayList<>();
        ReturnData<List<FunctionApi>> returnData = systemRemote.getFunctionApiListByCodes(String.join(",",grantApiCodeList));
        if (returnData == null) return new ArrayList<>();
        return returnData.getData();
    }

    /**
     * 获取会员授权码列表
     */
    @Override
    public List<String> getGrantFunctionApiCodeList(String memberTypeId) {
        return grantFunctionApiMapper.getGrantFunctionApiCodeList(memberTypeId);
    }

    /**
     * 更新权限
     */
    @Override
    public void updateGrantFunctionApiList(String memberTypeId, String[] apiCodes) {
        List<String> grantCodeList = getGrantFunctionApiCodeList(memberTypeId);
        // ### 添加新增的权限
        for (String apiCode : apiCodes) {
            if (!grantCodeList.contains(apiCode)) {
                GrantFunctionApi api = new GrantFunctionApi();
                api.setMemberTypeId(memberTypeId);
                api.setApiCode(apiCode);
                grantFunctionApiMapper.insert(api);
            }
        }
        // ### 移除失效的权限
        for (String functionApiId : grantCodeList) {
            if (!Arrays.asList(apiCodes).contains(functionApiId)) {
                removeGrantFunctionApi(memberTypeId, functionApiId);
            }
        }
        // ### 移除(收回)会员指向组织下所有下级组织失效的权限
        MemberType memberType = memberTypeService.getById(memberTypeId);
        removeChildGrantMenu(memberType.getOrganizeId(), apiCodes);
    }

    /// ### 收回所有下级平台的权限
    private void removeChildGrantMenu(String surOrganizeId, String[] apiCodes) {
        List<Organize> childOrganizeList = organizeService.getOrganizeListBySuperOrganizeId(surOrganizeId);
        for (Organize childOrganize : childOrganizeList) {
            // ### 移除组织失效的权限
            if (childOrganize.getMemberTypeId() == null) continue;
            List<String> grantCodeList = getGrantFunctionApiCodeList(childOrganize.getMemberTypeId());
            for (String apiCode : grantCodeList) {
                if (!Arrays.asList(apiCodes).contains(apiCode)) {
                    removeGrantFunctionApi(childOrganize.getMemberTypeId(), apiCode);
                }
            }
            // ### 递归遍历，移除所有下级平台组织的权限
            removeChildGrantMenu(childOrganize.getId(), apiCodes);
        }
    }

    @Override
    public void removeGrantFunctionApi(String memberTypeId, String apiCode) {
        QueryWrapper<GrantFunctionApi> wrapper = new QueryWrapper<>();
        wrapper.eq("member_type_id", memberTypeId);
        wrapper.eq("api_code", apiCode);
        grantFunctionApiMapper.delete(wrapper);
    }

}
